home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume91 / shells / cshel510 / part04 < prev    next >
Encoding:
Internet Message Format  |  1991-04-16  |  58.1 KB

  1. Path: news.larc.nasa.gov!amiga-request
  2. From: amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
  3. Subject: v91i091: CShell 5.10 - alternative command interface, Part04/06
  4. Reply-To: umueller@iiic.ethz.ch
  5. Newsgroups: comp.sources.amiga
  6. Message-ID: <comp.sources.amiga:v91i091@ab20.larc.nasa.gov>
  7. References: <comp.sources.amiga:v91i088@ab20.larc.nasa.gov>
  8. Date: 16 Apr 91 19:34:37 GMT
  9. Approved: tadguy@uunet.UU.NET (Tad Guy)
  10. X-Mail-Submissions-To: amiga@uunet.uu.net
  11. X-Post-Discussions-To: comp.sys.amiga.misc
  12.  
  13. Submitted-by: umueller@iiic.ethz.ch
  14. Posting-number: Volume 91, Issue 091
  15. Archive-name: shells/cshell-5.10/part04
  16.  
  17. #!/bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 4 (of 6)."
  24. # Contents:  comm3.c csh.doc.aa
  25. # Wrapped by tadguy@ab20 on Tue Apr 16 15:34:35 1991
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'comm3.c' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'comm3.c'\"
  29. else
  30. echo shar: Extracting \"'comm3.c'\" \(28599 characters\)
  31. sed "s/^X//" >'comm3.c' <<'END_OF_FILE'
  32. X/*
  33. X * COMM3.C
  34. X *
  35. X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
  36. X * Version 5.00L by Urban Mueller 17-Feb-91
  37. X *
  38. X */
  39. X
  40. X#include "shell.h"
  41. X
  42. X/* comm3.c */
  43. Xstatic void doassign(char *log, char *phy);
  44. Xstatic void assignlist(void);
  45. Xstatic int strings_in_file(char *s);
  46. Xstatic int htype_a_file(char *s);
  47. Xstatic void install_menu(char **mav, int mac);
  48. Xstatic int line_filter( char *(*line)(char *) );
  49. X
  50. Xstatic int
  51. Xmyfgets( char *buf, FILE *in )
  52. X{
  53. X    int l;
  54. X    char *ret;
  55. X    if( ret=fgets(buf,253,in) ) {
  56. X        l=strlen(buf);
  57. X        if( buf[l-1]!='\n' )
  58. X            buf[l]='\n', buf[l+1]=0;
  59. X    }
  60. X    return ret!=NULL && !dobreak();
  61. X}
  62. X
  63. Xdo_tee( void )
  64. X{
  65. X    char buf[256];
  66. X    FILE *out;
  67. X
  68. X    prepscroll( ac==1 );
  69. X    if( ac>2 ) { ierror( av[2], 500 ); return 20; }
  70. X    if( ac==1 ) out=stderr;
  71. X    else if( !(out=fopen( av[1], "w" ))) { pError( av[1] ); return 20; }
  72. X    while (myfgets(buf,stdin)) {
  73. X        fputs(buf, stdout);
  74. X        quickscroll();
  75. X        fprintf(out, "%s", buf);
  76. X    }
  77. X    if( ac!=1 ) fclose( out );
  78. X    return 0;
  79. X}
  80. X
  81. Xdo_head( char *garbage, int com )
  82. X{
  83. X    int i, n;
  84. X    FILE *f;
  85. X    char buf[256];
  86. X
  87. X    if (ac>2) {
  88. X        n=(int)(long)Atol(av[2]);
  89. X        if (IoErr()) {
  90. X            ierror(av[2],511);
  91. X            return 20;
  92. X        }
  93. X    } else n=10;
  94. X
  95. X    f=fopen(av[1], "r");
  96. X    if (f==NULL) {
  97. X        pError(av[1]);
  98. X        return 20;
  99. X    }
  100. X    if (com) {    /* tail specific part */
  101. X        i=0;
  102. X        while (fgets(buf, 256, f) && ! dobreak()) i++;
  103. X        rewind(f);
  104. X        if (n>i) n=i;
  105. X        i=i-n;
  106. X        while (i-- && fgets(buf, 256, f) && ! dobreak()) ;
  107. X    }
  108. X    for (i=1; i<=n && fgets(buf, 256, f) && ! dobreak(); i++)
  109. X        printf("%s", buf);
  110. X    fclose(f);
  111. X    return 0;
  112. X}
  113. X
  114. Xstatic int
  115. Xexword( char **src, char *buf )
  116. X{
  117. X    *buf=0;
  118. X    if( **src==0 ) return 0;
  119. X    while( **src && **src!=0xA0 )
  120. X        *buf++=*(*src)++;
  121. X    *buf=0;
  122. X    if( **src ) (*src)++;
  123. X    return 1;
  124. X}
  125. X
  126. Xstatic char helpfound=0;
  127. X
  128. Xvoid
  129. Xman( FILE *f, char *s)
  130. X{
  131. X    char buf[140], entry[100];
  132. X    int len=sprintf(entry, "    %s", s);
  133. X
  134. X    prepscroll(0);
  135. X    rewind(f);
  136. X    do                                  /* look for required argument */
  137. X        if (fgets(buf, 140, f) == NULL)
  138. X            return;
  139. X    while ( Strncmp(entry, buf, len) );
  140. X    helpfound=1;
  141. X    do {                                /* display help */
  142. X        quickscroll();
  143. X        printf("%s", buf);
  144. X        if (fgets(buf, 140, f) == NULL) return;
  145. X    } while ( ( !isalphanum(*buf) ) && strncmp(buf, "    ", 4) && !dobreak() );
  146. X}
  147. X
  148. X
  149. Xdo_man( void )
  150. X{
  151. X    FILE *f;
  152. X    int i;
  153. X    char buf[200], name[60], *src, *var, docfound=0;
  154. X
  155. X    buf[0]=0;
  156. X    if( var=get_var(LEVEL_SET,"_man" ) )
  157. X        strcpy(buf,var);
  158. X
  159. X    if (ac==1) ac=2, av[1]="MAN";
  160. X    for (i=1; i<ac; i++) {
  161. X        src=buf, helpfound=0;
  162. X        while( exword( &src, name) )
  163. X            if( f=fopen(name, "r") ) {
  164. X                docfound=1;
  165. X                man(f, av[i]);
  166. X                fclose(f);
  167. X                if( helpfound )
  168. X                    break;
  169. X            }
  170. X        if( !docfound )
  171. X            fprintf(stderr,"%s not found\n",buf);
  172. X        else if( !helpfound )
  173. X            fprintf(stderr, "Help not found for %s\n", av[i]);
  174. X    }
  175. X    return 0;
  176. X}
  177. X
  178. Xdo_assign( void )
  179. X{
  180. X    int i;
  181. X
  182. X    if     (  ac==1  ) assignlist();
  183. X    else if(  ac==2  ) doassign(av[1], NULL);
  184. X    else if( !(ac&1) ) ierror(NULL, 500);
  185. X    else
  186. X        for( i=1; i<ac; i+=2 )
  187. X            doassign( av[i],av[i+1] );
  188. X    return 0;
  189. X}
  190. X
  191. Xstatic char *assign_errors[4]={
  192. X    "",
  193. X    "Name %s is not valid\n",
  194. X    "Weird error\n",
  195. X    "Can't cancel %s:\n"
  196. X    };
  197. X
  198. X
  199. Xstatic void
  200. Xdoassign(char *log, char *phy)
  201. X{
  202. X    int last=strlen(log) - 1;
  203. X
  204. X    if (log[last] != ':') fprintf(stderr, "Bad name %s\n", log);
  205. X    else {
  206. X        log[last] = 0;
  207. X        if( options && phy && o_kick20 ) {
  208. X            BPTR lock;
  209. X            int succ=0;
  210. X            if     ( options&1 ) succ=AssignLate( (UBYTE*)log,(UBYTE*)phy );
  211. X            else if( options&2 ) succ=AssignPath( (UBYTE*)log,(UBYTE*)phy );
  212. X            else if( options&4 )
  213. X                if( lock=Lock(phy,ACCESS_READ) )
  214. X                    if( !(succ=AssignAdd(log,lock)))
  215. X                        UnLock(lock);
  216. X            if( !succ )
  217. X                pError( log );
  218. X        } else if( !(options&4) ) {
  219. X            int err=Assign(log, phy);
  220. X            fprintf(stderr,assign_errors[err],err==1?phy:log);
  221. X        }
  222. X    }
  223. X}
  224. X
  225. Xextern struct RootNode2x *RootNode;
  226. X#define ENTRIES 128
  227. X
  228. Xstatic void
  229. Xassignlist()
  230. X{
  231. X    char *ptr, *log, **arr;
  232. X    int ctr, i;
  233. X
  234. X    if(!(arr=expand_devs()))
  235. X        return;
  236. X
  237. X    printf("Devices:\n");
  238. X    for (i=ctr=0; arr[i] && *arr[i]==1; i++) {
  239. X        printf("%-8s",arr[i]+1);
  240. X        if (ctr++ == 5) { ctr=0; printf("\n"); }
  241. X    }
  242. X
  243. X    printf("\n\nVolumes:\n");
  244. X    for( ; arr[i] && *arr[i]==2; i++ )
  245. X        printf( "%-16s [Mounted]\n",arr[i]+1);
  246. X
  247. X    printf("\nDirectories:\n");
  248. X    for( ; arr[i] && !dobreak(); i++ ) {
  249. X        log=arr[i]+1; ptr=log+strlen(log)+1;
  250. X        switch( *(log-1)) {
  251. X        case 3:
  252. X            printf("%-20s%s\n", log, ptr);
  253. X            for(;;) {
  254. X                ptr+=strlen(ptr)+1;
  255. X                if( !*ptr ) break;
  256. X                    printf("%-19s+%s\n", "", ptr);
  257. X            }
  258. X            break;
  259. X        case 4: printf("%-20s<%s>\n", log, ptr); break;
  260. X        case 5: printf("%-20s[%s]\n", log, ptr); break;
  261. X        }
  262. X    }
  263. X
  264. X    free_expand( arr );
  265. X}
  266. X
  267. Xchar **
  268. Xexpand_devs(void)
  269. X{
  270. X    static char Type[]={1,3,2,4,5};
  271. X    struct DosInfo *info=(void*)((long)RootNode->rn_Info*4);
  272. X    struct DosList2x *list=(void*)((long) info->di_DevInfo*4);
  273. X    struct AssignList2x *path;
  274. X    char buf[256], **arr, *ptr;
  275. X    int n;
  276. X
  277. X    if( !(arr=malloc(ENTRIES*sizeof(char *))))
  278. X        return NULL;
  279. X
  280. X    Forbid();
  281. X    for( n=0; list && n<ENTRIES; list=(void*)((long)list->dol_Next*4)) {
  282. X        if( list->dol_Type<0 || list->dol_Type>DLST_NONBINDING )
  283. X            continue;
  284. X        ptr=buf;
  285. X        *ptr++=Type[list->dol_Type];
  286. X        ptr+=BtoCStr(ptr,list->dol_Name,200);
  287. X        *ptr++=':'; *ptr++=0;
  288. X        switch( list->dol_Type) {
  289. X        case DLST_DIRECTORY : 
  290. X            if(list->dol_Lock)
  291. X                PathName(list->dol_Lock, ptr, 200);
  292. X            else 
  293. X                strcpy(ptr,"Nonexisting lock");
  294. X            ptr+=strlen(ptr)+1;                    
  295. X            path=(void*)list->dol_misc.dol_assign.dol_List;
  296. X            for( ; path; path=(void*)path->al_Next ) {
  297. X                if(list->dol_Lock)
  298. X                    PathName(path->al_Lock, ptr, 200);
  299. X                else 
  300. X                    strcpy(ptr,"Nonexisting lock");
  301. X                ptr+=strlen(ptr)+1;
  302. X            }
  303. X            *ptr++=0;
  304. X            break;
  305. X        case DLST_LATE      : 
  306. X        case DLST_NONBINDING:
  307. X            ptr+= sprintf(ptr,"%s",list->dol_misc.dol_assign.dol_AssignName);
  308. X            *ptr++=0;
  309. X            break;
  310. X        }
  311. X        arr[n]=salloc(ptr+1-buf);
  312. X        memcpy(arr[n++],buf,ptr+1-buf);
  313. X    }
  314. X    arr[n]=NULL;
  315. X    Permit();
  316. X
  317. X    QuickSort( arr, n );
  318. X
  319. X    return arr;
  320. X}
  321. X
  322. X
  323. Xdo_join( void )
  324. X{
  325. X    BPTR sou, dest;
  326. X    char *buffer;
  327. X    int i;
  328. X    long n;
  329. X    char *namedest=av[--ac];
  330. X
  331. X    if (options==0 && exists(namedest)) { ierror(namedest,203); return 20; }
  332. X    if ( (buffer=malloc(8192)) == NULL ) { ierror(NULL,103); return 20; }
  333. X    if ( (dest=Open(namedest, MODE_NEWFILE)) == NULL )
  334. X        { pError(namedest); goto fail1; }
  335. X    for (i=1; i<ac; i++) {
  336. X        if ( (sou=Open(av[i], MODE_OLDFILE)) == NULL ) pError(av[i]);
  337. X        else
  338. X            while( (n=Read(sou, buffer, 8192L)) > 0 )
  339. X                if (Write(dest, buffer, n) != n)
  340. X                    { pError(namedest); Close(sou); goto fail2; }
  341. X        Close(sou);
  342. X    }
  343. Xfail2:
  344. X    Close(dest);
  345. Xfail1:
  346. X    free(buffer);
  347. X    return 0;
  348. X}
  349. X
  350. X#define BUFDIM 512L
  351. X#define MAXSTR 256
  352. X
  353. Xint minstr;
  354. X
  355. Xstatic int
  356. Xstrings_in_file(char *s)
  357. X{
  358. X    char c;
  359. X    char readbuf[BUFDIM+1], strbuf[MAXSTR+1];
  360. X    int i, strctr=0;
  361. X    BPTR fh;
  362. X    int out, n;
  363. X
  364. X    prepscroll(0);
  365. X    if ( fh=Open(s, MODE_OLDFILE) ) {
  366. X        fprintf(stderr, "Strings in %s (len>=%d):\n",s,minstr);
  367. X        while ( (n=(int)Read(fh, readbuf, BUFDIM)) > 0 && !CHECKBREAK() )
  368. X            for (i=0; i<n; i++) {
  369. X                c=readbuf[i];
  370. X                if (c<0x20 || c>0x7f) {
  371. X                    out=(strctr>=minstr);
  372. X                    if (!out) strctr=0;
  373. X                } else {
  374. X                    strbuf[strctr++]=c;
  375. X                    out=(strctr>=BUFDIM);
  376. X                }
  377. X                if (out) {
  378. X                    strbuf[strctr]='\0';
  379. X                    puts(strbuf);
  380. X                    quickscroll();
  381. X                    strctr=0;
  382. X                }
  383. X            }
  384. X        Close(fh);
  385. X    } else
  386. X        pError(s);
  387. X    return 0;
  388. X}
  389. X
  390. Xdo_strings( void )
  391. X{
  392. X    minstr=myatoi(av[--ac],1,255);
  393. X    all_args( strings_in_file, 0);
  394. X    return 0;
  395. X}
  396. X
  397. XBPTR myfile[MAXMYFILES];
  398. X
  399. Xdo_open( void )
  400. X{
  401. X    long mode;
  402. X    int n;
  403. X
  404. X    switch (toupper(av[2][0])) {
  405. X        case 'R': mode=MODE_OLDFILE; break;
  406. X        case 'W': mode=MODE_NEWFILE; break;
  407. X        default : ierror(NULL,500); return 1;
  408. X    }
  409. X    n=myatoi(av[3],0,MAXMYFILES-1); if (atoierr) return 20;
  410. X    if (myfile[n]) myclose(n);
  411. X    myfile[n]=Open(av[1],mode);
  412. X    return myfile[n]==NULL;
  413. X}
  414. X
  415. Xdo_close( void )
  416. X{
  417. X    int i, n;
  418. X
  419. X    if (ac==1)
  420. X        for (i=1; i<MAXMYFILES; i++)
  421. X            myclose(i);
  422. X    for (i=1; i<ac; i++) {
  423. X        n=myatoi(av[i],0,MAXMYFILES-1); if (atoierr) return 20;
  424. X        myclose(n);
  425. X    }
  426. X    return 0;
  427. X}
  428. X
  429. Xvoid
  430. Xmyclose(int n)
  431. X{
  432. X    if (myfile[n]) { Close(myfile[n]); myfile[n]=NULL; }
  433. X}
  434. X
  435. Xdo_fileslist( void )
  436. X{
  437. X    int i, flag=0;
  438. X
  439. X    printf("Open files:");
  440. X    for (i=0; i<MAXMYFILES; i++)
  441. X        if (myfile[i]) { printf(" %d",i); flag=1; }
  442. X    if (!flag) printf(" None!");
  443. X    printf("\n");
  444. X    return 0;
  445. X}
  446. X
  447. XBPTR
  448. XextOpen( char *name, long mode )
  449. X{
  450. X    if (name[0]=='.') return myfile[atoi(name+1)];
  451. X    return Open(name,mode);
  452. X}
  453. X
  454. X
  455. Xvoid
  456. XextClose(BPTR fh)
  457. X{
  458. X    int i;
  459. X
  460. X    for (i=0; i<MAXMYFILES; i++)
  461. X        if (myfile[i]==fh) return;
  462. X    Close(fh);
  463. X}
  464. X
  465. Xdo_basename( void )
  466. X{
  467. X    set_var(LEVEL_SET, av[1], BaseName(av[2]));
  468. X    return 0;
  469. X}
  470. X
  471. Xdo_tackon( void )
  472. X{
  473. X    char buf[256];
  474. X
  475. X    strcpy(buf, av[2]);
  476. X    TackOn(buf, av[3]);
  477. X    set_var(LEVEL_SET, av[1], buf);
  478. X    return 0;
  479. X}
  480. X
  481. Xextern char shellres[];
  482. X
  483. Xdo_resident( void )
  484. X{
  485. X    int i=1;
  486. X    struct ResidentProgramNode *p;
  487. X    char buf[256];
  488. X
  489. X    if (options==0 && ac>1) options=1;
  490. X    switch (options) {
  491. X    case 0:
  492. X        ObtainSemaphore (& (ArpBase->ResPrgProtection) );
  493. X        if (p=ArpBase->ResidentPrgList) {
  494. X            printf("Name             Users Access\n");
  495. X            for (; p; p=p->rpn_Next)
  496. X                printf("%-17s%5d%6d\n",
  497. X                    p->rpn_Name, p->rpn_Usage, p->rpn_AccessCnt);
  498. X        } else
  499. X            printf("No resident program(s)\n");
  500. X        ReleaseSemaphore(& (ArpBase->ResPrgProtection) );
  501. X        break;
  502. X    case 1:
  503. X        for (; i<ac; i++)
  504. X            if (loadres(av[i]))
  505. X                printf("OK! %s is now resident\n", BaseName(av[i]));
  506. X            else
  507. X                pError(av[i]);
  508. X        break;
  509. X    case 2:
  510. X        for (; i<ac; i++)
  511. X            if (RemResidentPrg(av[i])) ierror(av[i],202);
  512. X            else printf("Removed %s\n",av[i]);
  513. X        break;
  514. X    case 4:
  515. X        for (; i<ac; i++) {
  516. X            if( !o_resident ) {
  517. X                Setenv(shellres,"1");
  518. X                o_resident=1;
  519. X            }
  520. X            sprintf(buf,"res_%s",av[i]);
  521. X            Setenv(buf,"1");
  522. X        }
  523. X        break;
  524. X    default:
  525. X        ierror(NULL,500);
  526. X        break;
  527. X    }
  528. X    return 0;
  529. X}
  530. X
  531. Xint
  532. Xloadres(char *s)
  533. X{
  534. X    BPTR seg;
  535. X
  536. X    if (seg=(BPTR)LoadPrg(s)) AddResidentPrg(seg,BaseName(s));
  537. X    return (seg != NULL);
  538. X}
  539. X
  540. Xstatic struct ProcessControlBlock pcb={
  541. X    4000,        /* pcb_StackSize    */
  542. X    0,            /* pcb_Pri            */
  543. X    };
  544. X/* remaining fields are NULL */
  545. X
  546. Xdo_truerun(char *avline, int backflag)
  547. X{
  548. X    char name[100], *args, buf[10];
  549. X    int cli;
  550. X
  551. X    if (backflag) {
  552. X        pcb.pcb_Control=NULL;
  553. X        pcb.pcb_Input=pcb.pcb_Output=Open("NIL:",MODE_OLDFILE);
  554. X    } else {
  555. X        pcb.pcb_Control=NULL;
  556. X        pcb.pcb_Input=pcb.pcb_Output =NULL;
  557. X    }
  558. X    args=next_word(next_word(avline));
  559. X
  560. X    if((cli=ASyncRun(av[1],args,&pcb))<0)
  561. X        if (dofind(av[1], "", name,v_path))
  562. X            cli=ASyncRun(name,args,&pcb);
  563. X
  564. X    sprintf(buf,"%d",cli);
  565. X    set_var(LEVEL_SET,"_newproc",buf);
  566. X
  567. X    if( cli<0 ) {
  568. X        ierror(av[1],205);
  569. X        return 20;
  570. X    }
  571. X    return 0;
  572. X}
  573. X
  574. Xint
  575. Xexists( char *name )
  576. X{
  577. X    BPTR lock;
  578. X
  579. X    if (lock=Lock(name,ACCESS_READ)) {
  580. X        UnLock(lock);
  581. X        return 1;
  582. X    }
  583. X    return 0;
  584. X}
  585. X
  586. Xdo_aset( void )
  587. X{
  588. X    Setenv(av[1],av[2]);
  589. X    return 0;
  590. X}
  591. X
  592. X#define HTYPELINE 16L
  593. X
  594. Xstatic int
  595. Xhtype_a_file( char *s )
  596. X{
  597. X    BPTR fh;
  598. X    long n, filesize=0;
  599. X    char buf[HTYPELINE+1];
  600. X    char out[80], *put;
  601. X    int i;
  602. X
  603. X    if ( (fh=Open(s,MODE_OLDFILE))==NULL ) { pError(s); return 20; }
  604. X    prepscroll(0);
  605. X    while ( (n=Read(fh,buf,HTYPELINE))>0 && !dobreak()) {
  606. X        put=out;
  607. X        put+=sprintf(put,"%06lx: ",filesize);
  608. X        filesize+=n;
  609. X        for (i=0; i<n; i++) {
  610. X            put+=sprintf( put,(i&3) ? "%02x" : " %02x",buf[i]);
  611. X            if ((buf[i]&127)<0x20) buf[i]='.';
  612. X        }
  613. X        for ( ; i<HTYPELINE; i++) {
  614. X            put+=sprintf( put, (i&3) ? "  " : "   ");
  615. X            buf[i]=' ';
  616. X        }
  617. X        buf[i]=0;
  618. X        sprintf(put,"    %s",buf);
  619. X        puts(out);
  620. X        quickscroll();
  621. X    }
  622. X    Close(fh);
  623. X    return 0;
  624. X}
  625. X
  626. Xdo_htype( void )
  627. X{
  628. X    all_args( htype_a_file, 0);
  629. X    return 0;
  630. X}
  631. X
  632. Xdo_stack( void )
  633. X{
  634. X    long n;
  635. X
  636. X    if (ac>1) {
  637. X        n=Atol(av[1]);
  638. X        if (!IoErr()) Mycli->cli_DefaultStack=(long)(n >> 2L);
  639. X    }
  640. X    else printf("current stack size is %ld bytes\n",
  641. X                (long)Mycli->cli_DefaultStack << 2L);
  642. X    return 0;
  643. X}
  644. X
  645. Xdo_fault( void )
  646. X{
  647. X    struct PERROR *p;
  648. X    int i, n;
  649. X
  650. X    for (i=1; i<ac; i++) {
  651. X        n=myatoi(av[i],0,32767);
  652. X        if (!atoierr) {
  653. X            for (p=Perror; p->errnum && p->errnum!=n; p++);
  654. X            if (p->errnum)
  655. X                printf("Fault %d: %s\n",n,p->errstr);
  656. X            else
  657. X                printf("Fault %d not recognized\n",n);
  658. X        }
  659. X    }
  660. X    return 0;
  661. X}
  662. X
  663. Xstruct rpncommand {
  664. X    char *str;
  665. X    int parsin, parsout;
  666. X    };
  667. X
  668. Xstatic struct rpncommand rpn[]={
  669. X    "+",    2,    1,
  670. X    "-",    2,    1,
  671. X    "*",    2,    1,
  672. X    "/",    2,    1,
  673. X    "%",    2,    1,
  674. X    "&",    2,    1,
  675. X    "|",    2,    1,
  676. X    "~",    1,    1,
  677. X    ">",    2,    1,
  678. X    "<",    2,    1,
  679. X    "==",    2,    1,
  680. X    "!",    1,    1,
  681. X    "MAX",    2,    1,
  682. X    "MIN",    2,    1,
  683. X    "DUP",    1,    2,
  684. X    "DROP",    1,    0,
  685. X    "SWAP",    2,    2,
  686. X    "HELP",    0,    0,
  687. X    NULL,    0,    1,    /* this looks for a number */
  688. X};
  689. X
  690. Xstatic long stack[50];
  691. Xstatic int sp;
  692. X
  693. X
  694. Xeval_rpn( char **av, int ac, int flag )
  695. X{
  696. X    char *zero="Division by zero\n";
  697. X    struct rpncommand *temp;
  698. X    long n0, n1, t;
  699. X    int j, i=0, oldsp=sp;
  700. X
  701. X    for (; i<ac; i++) {
  702. X        for (j=0; rpn[j].str && Strcmp(rpn[j].str,av[i]); j++) ;
  703. X        n0=stack[sp-1];
  704. X        n1=stack[sp-2];
  705. X        sp -= (rpn[j].parsin);
  706. X        if (sp<0) { fprintf(stderr, "RPN: Empty stack\n"); goto error; }
  707. X        switch (j) {
  708. X          case 0:    n0 += n1;            break;
  709. X          case 1:    n0 = n1-n0;            break;
  710. X          case 2:    n0 *= n1;            break;
  711. X          case 3:    if(n0) n0=n1/n0; else fprintf(stderr,zero); break;
  712. X          case 4:    if(n0) n0=n1%n0; else fprintf(stderr,zero); break;
  713. X          case 5:    n0 &= n1;            break;
  714. X          case 6:    n0 |= n1;            break;
  715. X          case 7:    n0 =  ~n0    ;        break;
  716. X          case 8:    n0 = (n1 > n0);        break;
  717. X          case 9:    n0 = (n1 < n0);        break;
  718. X          case 10:    n0 = (n0 == n1);    break;
  719. X          case 11:    n0 = !n0;            break;
  720. X          case 12:    n0=n1>n0 ? n1 : n0;    break;
  721. X          case 13:    n0=n1<n0 ? n1 : n0;    break;
  722. X          case 14:    n1=n0;                break;
  723. X          case 15:    t=n0; n0=n1; n1=t;    break;
  724. X          case 16:                        break;
  725. X          case 17:    printf("In Commands Out\n");
  726. X            for (temp=rpn; temp->str; temp++)
  727. X                printf(" %d %-10s%d\n",
  728. X                temp->parsin,temp->str,temp->parsout);
  729. X            break;
  730. X          default:    n0=Atol(av[i]);
  731. X                if (IoErr()) {
  732. X                    fprintf(stderr, "Bad RPN cmd: %s\n",av[i]);
  733. X                    goto error;
  734. X                }
  735. X                break;
  736. X          }
  737. X        stack[sp]=n0;
  738. X        stack[sp+1]=n1;
  739. X        sp += rpn[j].parsout;
  740. X    }
  741. X    if( flag && sp-1)
  742. X        fprintf( 
  743. X          stderr,
  744. X          "RPN: Stack not empty\n"
  745. X        );
  746. X
  747. Xexit:
  748. X    t=sp; sp=oldsp;
  749. X    if( flag )
  750. X        return stack[t-1]; /* return top value */
  751. X    else 
  752. X        return t-sp;
  753. X
  754. Xerror:
  755. X    sp=oldsp;
  756. X    return 0;
  757. X}
  758. X
  759. X
  760. Xdo_rpn(char *garbage,int ifflag) /* ifflag!=0 if called from if */
  761. X{
  762. X    int i=1;
  763. X    long t;
  764. X
  765. X    t=eval_rpn( av+i, ac-i, ifflag );
  766. X    if (ifflag) return t;              /* called from if: return top value */
  767. X    for (i=sp+t-1;i>=sp;i--) printf("%ld\n", stack[i]);/* else print stack */
  768. X
  769. X    return t ? 0 : 20;
  770. X}
  771. X
  772. Xdo_path( void )
  773. X{
  774. X    ULONG ll, ll1, *lp, new, *newp;
  775. X    char buf[256];
  776. X    char buf2[256];
  777. X    BPTR lock;
  778. X    int i;
  779. X
  780. X    if( options&1 ) {
  781. X        Forbid();
  782. X        for( ll= Mycli->cli_CommandDir; ll; ll= ll1 ) {
  783. X            lp=(ULONG *)(4*ll);
  784. X            ll1=*lp;
  785. X            DosFreeMem( lp );
  786. X        }
  787. X        Mycli->cli_CommandDir=0;
  788. X        Permit();
  789. X    } else if( ac==1 ) {     /* Should Forbid() here, but puts() Permit()s */
  790. X        puts("Current dir"); /* and failure here is not really harmful...  */
  791. X        for( ll= Mycli->cli_CommandDir; ll; ll= *lp ) {
  792. X            lp=(ULONG *)(4*ll);
  793. X            PathName(lp[1], buf, 256L);
  794. X            puts(buf);
  795. X        }
  796. X        puts("C:");
  797. X        return 0;
  798. X    }
  799. X    Forbid();
  800. X    for( i=1; i<ac; i++ ) {
  801. X        if( !(lock=Lock(av[i],ACCESS_READ)) ) {
  802. X            pError(av[i]);
  803. X            continue;
  804. X        }
  805. X        PathName(lock, buf, 256L);
  806. X        for( ll= Mycli->cli_CommandDir, lp=NULL; ll; ll= *lp ) {
  807. X            lp=(ULONG *)(4*ll);
  808. X            PathName(lp[1],buf2,256L);
  809. X            if( !Strcmp(buf,buf2) ) {
  810. X                UnLock(lock);
  811. X                break;
  812. X            }
  813. X        }
  814. X        if( !ll && (newp=DosAllocMem( 8 ))) {
  815. X            newp[1]=lock;
  816. X            new =(ULONG)newp/4;
  817. X            if( lp )
  818. X                *lp=new;
  819. X            else
  820. X                Mycli->cli_CommandDir=new;
  821. X        }
  822. X    }
  823. X    Permit();
  824. X    return 0;
  825. X}
  826. X
  827. Xdo_pri( void )
  828. X{
  829. X    int t, pri;
  830. X    struct Process *proc;
  831. X
  832. X    t=(int)(long)FindCLI(0L);
  833. X    t=myatoi(av[1],0,t); if (atoierr) return 20;
  834. X    pri=myatoi(av[2],-128,127); if (atoierr) return 20;
  835. X    Forbid();
  836. X    proc=(t==0 ? Myprocess : FindCLI((long)t));
  837. X    if (proc==NULL) fprintf(stderr, "process not found\n");
  838. X    else SetTaskPri((struct Task *)proc, (long)pri);
  839. X    Permit();
  840. X    return 0;
  841. X}
  842. X
  843. Xdo_strleft( void )
  844. X{
  845. X    int n;
  846. X
  847. X    n=posatoi(av[3]); if (atoierr) return 20;
  848. X    set_var_n(LEVEL_SET, av[1], av[2], n);
  849. X    return 0;
  850. X}
  851. X
  852. Xdo_strright( void )
  853. X{
  854. X    int n, len=strlen(av[2]);
  855. X
  856. X    n=posatoi(av[3]); if (atoierr) return 20;
  857. X    if( n>len ) n=len;
  858. X    set_var(LEVEL_SET, av[1], av[2]+len-n );
  859. X    return 0;
  860. X}
  861. X
  862. Xdo_strmid( void )
  863. X{
  864. X    int n1, n2=999999, len=strlen(av[2]);
  865. X
  866. X    n1=myatoi(av[3],1,999999)-1; if (atoierr) return 20;
  867. X    if (n1>len) n1=len;
  868. X    if (ac>4) {
  869. X        n2=posatoi(av[4]); if (atoierr) return 20;
  870. X    }
  871. X    set_var_n(LEVEL_SET, av[1], av[2]+n1, n2);
  872. X    return 0;
  873. X}
  874. X
  875. Xdo_strlen( void )
  876. X{
  877. X    char buf[16];
  878. X
  879. X    sprintf(buf,"%d",strlen(av[2]));
  880. X    set_var(LEVEL_SET, av[1], buf);
  881. X    return 0;
  882. X}
  883. X
  884. Xint atoierr;
  885. X
  886. Xmyatoi(char *s,int mmin,int mmax)
  887. X{
  888. X    int n;
  889. X
  890. X    n=Atol(s);
  891. X    if (atoierr=IoErr())
  892. X        ierror(s,511);
  893. X    else if (n<mmin || n>mmax) {
  894. X        atoierr=1; n=mmin;
  895. X        fprintf( stderr, "%s(%d) not in (%d,%d)\n",s,n,mmin,mmax );
  896. X    }
  897. X    return n;
  898. X}
  899. X
  900. Xunlatoi(char *s)
  901. X{
  902. X    int n=Atol(s);
  903. X    if (atoierr=IoErr())
  904. X        ierror(s,511), n=0;
  905. X    return n;
  906. X}
  907. X
  908. Xposatoi(char *s)
  909. X{
  910. X    int n=Atol(s);
  911. X    if (atoierr=IoErr())
  912. X        ierror(s,511);
  913. X    else if (n<0 )
  914. X        atoierr=1, n=0, fprintf( stderr, "%s must be positive\n",s );
  915. X    return n;
  916. X}
  917. X
  918. X
  919. Xdo_fltlower( void )
  920. X{
  921. X    return line_filter( strlwr );
  922. X}
  923. X
  924. Xdo_fltupper( void )
  925. X{
  926. X    return line_filter( strupr );
  927. X}
  928. X
  929. X#if 0
  930. Xchar *
  931. Xstripcr( char *get )
  932. X{
  933. X    char *old=get, *put;
  934. X
  935. X    for( put=get; *get; get++ )
  936. X        if( *get!=13 )
  937. X            *put++=*get;
  938. X    *put++=0;
  939. X    return old;
  940. X}
  941. X
  942. Xdo_fltstripcr( void )
  943. X{
  944. X    return line_filter( stripcr );
  945. X}
  946. X#endif
  947. X
  948. Xint
  949. Xline_filter( char *(*func)( char * ) )
  950. X{
  951. X    char buf[256];
  952. X
  953. X    while (!CHECKBREAK() && gets(buf))
  954. X        puts((*func)(buf));
  955. X    return 0;
  956. X}
  957. X
  958. Xdo_linecnt( void )
  959. X{
  960. X    int count=0;
  961. X    char buf[256];
  962. X
  963. X    while (!CHECKBREAK() && gets(buf)) ++count;
  964. X    printf("%d lines\n",count);
  965. X    return 0;
  966. X}
  967. X
  968. Xdo_uniq( void )
  969. X{
  970. X    int firstline=1;
  971. X    char buf[256], oldbuf[256];
  972. X
  973. X    while (!CHECKBREAK() && gets(buf)) {
  974. X        if ( firstline || strcmp(buf, oldbuf)) {
  975. X            strcpy(oldbuf, buf);
  976. X            puts(buf);
  977. X        }
  978. X        firstline=0;
  979. X    }
  980. X    return 0;
  981. X}
  982. X
  983. X
  984. X#define RXFB_RESULT  17
  985. X
  986. Xstatic struct rexxmsg {
  987. X    struct Message cm_Node;
  988. X    LONG   RFU1;
  989. X    LONG   RFU2;
  990. X    LONG   rm_Action;
  991. X    LONG   rm_Result1;
  992. X    LONG   rm_Result2;
  993. X    char   *cm_Args[16];
  994. X    LONG   RFU7;
  995. X    LONG   RFU8;
  996. X    LONG   RFU9;
  997. X    LONG   RFU10;
  998. X    LONG   RFU11;
  999. X    LONG   RFU12;
  1000. X} mymsg;
  1001. X
  1002. Xdo_rxsend( char *avline )
  1003. X{
  1004. X    int i;
  1005. X    long result;
  1006. X    struct MsgPort *port, *reply;
  1007. X    long len;
  1008. X    char buf[20], *resptr;
  1009. X
  1010. X    if (!(port = FindPort(av[1])))
  1011. X        { fprintf(stderr, "No port %s!\n", av[1]); return 20; }
  1012. X    mymsg.cm_Node.mn_Node.ln_Type = NT_MESSAGE;
  1013. X    mymsg.cm_Node.mn_Length = sizeof(struct rexxmsg);
  1014. X    mymsg.rm_Action = (options&1 ? 1L << RXFB_RESULT : 0);
  1015. X    if (!(reply = CreatePort(NULL, 0L))) {
  1016. X        fprintf(stderr, "No reply port\n");
  1017. X        return 20;
  1018. X    }
  1019. X    mymsg.cm_Node.mn_ReplyPort = reply;
  1020. X
  1021. X    if( options&2 )
  1022. X        av[2]=compile_av( av,2,ac,' ',0), ac=3;
  1023. X    for ( i=2; i<ac; i++) {
  1024. X        mymsg.cm_Args[0] = av[i];
  1025. X        mymsg.rm_Result2 = 0;        /* clear out the last result. */
  1026. X        PutMsg(port, &mymsg.cm_Node);
  1027. X        WaitPort(reply);
  1028. X
  1029. X        if (options&1) {
  1030. X            if( (result=mymsg.rm_Result2)<1000000 ) { /* so does it AREXX */
  1031. X                sprintf(buf,"%d",result);              
  1032. X                set_var(LEVEL_SET,v_result,buf);
  1033. X            } else {
  1034. X                resptr=(char *)(result-4);
  1035. X                len=*(long *)resptr;
  1036. X                memmove(resptr,resptr+4,len);  /* Null terminate */
  1037. X                resptr[len]=0;      
  1038. X                set_var(LEVEL_SET,v_result,resptr);
  1039. X                FreeMem(resptr, len+4 );
  1040. X            }
  1041. X        } else 
  1042. X            unset_var( LEVEL_SET, v_result );
  1043. X    }
  1044. X    if( options&2 )
  1045. X        free( av[2] );
  1046. X
  1047. X    if (reply) DeletePort(reply);
  1048. X    return 0;
  1049. X}
  1050. X
  1051. Xstatic char *rxreturn;
  1052. X
  1053. Xdo_rxrec( void )
  1054. X{
  1055. X    struct MsgPort *port;
  1056. X    struct rexxmsg *msg;
  1057. X    char *portname, *str;
  1058. X
  1059. X    if (ac > 1)
  1060. X        portname=av[1];
  1061. X    else
  1062. X        portname="rexx_csh";
  1063. X
  1064. X    port=CreatePort(portname, 0L);
  1065. X    if (port==NULL) {
  1066. X        fprintf(stderr, "Can't have MsgPort %s\n", portname);
  1067. X        return 20;
  1068. X    }
  1069. X    for (;;) {
  1070. X        WaitPort(port);
  1071. X        while (msg=(struct rexxmsg *)GetMsg(port)) {
  1072. X            if ( ! Strcmp(msg->cm_Args[0], "bye")) {
  1073. X                ReplyMsg((struct Message *)msg);
  1074. X                DeletePort(port);
  1075. X                return 0;
  1076. X            }
  1077. X            rxreturn=NULL;
  1078. X            exec_command(msg->cm_Args[0]);
  1079. X            if (msg->rm_Action & (1L << RXFB_RESULT)) {
  1080. X                if( rxreturn ) {
  1081. X                    str= SAllocMem( strlen( rxreturn )+5 , 0 );
  1082. X                    *(long *)str=strlen( rxreturn );
  1083. X                    strcpy( str+4, rxreturn );
  1084. X                    msg->rm_Result2=(long)str;
  1085. X                } else {
  1086. X                    str = get_var(LEVEL_SET, v_lasterr);
  1087. X                    msg->rm_Result2=(str) ? atoi(str) : 20;
  1088. X                }
  1089. X            }
  1090. X            ReplyMsg((struct Message *)msg);
  1091. X        }
  1092. X    }
  1093. X}
  1094. X
  1095. Xint
  1096. Xdo_waitport( void )
  1097. X{
  1098. X    int count=4*10;
  1099. X    struct MsgPort *port=NULL;
  1100. X
  1101. X    if( ac==3 ) 
  1102. X        { count=2*myatoi(av[2],0, 32000); if( atoierr ) return 20; }
  1103. X
  1104. X    while( --count>=0 && !(port=FindPort(av[1])) && !dobreak() )
  1105. X        Delay(12);
  1106. X
  1107. X    return port ? 0 : 20;
  1108. X}
  1109. X
  1110. Xint
  1111. Xdo_rxreturn( void )
  1112. X{
  1113. X    rxreturn=compile_av( av, 1, ac, ' ', 1 );
  1114. X    return 0;
  1115. X}
  1116. X
  1117. Xdo_ascii( void )
  1118. X{
  1119. X    int x=1, y, c, c1, t;
  1120. X    char *fmt1=" %3d %c%c |", *fmt2=" %4d";
  1121. X
  1122. X    if( options&1 ) fmt1=" %3o %c%c |", fmt2="%4o";
  1123. X    if( options&2 ) fmt1=" %3x %c%c |", fmt2="%4x";
  1124. X    if( ac==x )
  1125. X        for( y=0; y<32 && !dobreak(); y++ ) {
  1126. X            printf("|");
  1127. X            for( x=0; x<8; x++ ) {
  1128. X                c1=c=y+32*x; t=' ';
  1129. X                if( c<32 ) t='^', c1+=64;
  1130. X                printf(fmt1,c, t, c1<128 || c1>=160?c1:'.');
  1131. X            }
  1132. X            printf("\n");
  1133. X        }
  1134. X    else 
  1135. X        for( ; x<ac && !dobreak(); x++ ) {
  1136. X            for( y=0; y<strlen(av[x]); y++ )
  1137. X                printf(fmt2,av[x][y]);
  1138. X            printf("\n");
  1139. X        }
  1140. X    return 0;
  1141. X}
  1142. X
  1143. Xvoid
  1144. Xappendslash( char *path )
  1145. X{
  1146. X    int c;
  1147. X
  1148. X    if( (c=path[strlen(path)-1]) !='/' && c!=':' )
  1149. X        strcat(path,"/");
  1150. X}
  1151. X
  1152. Xstatic void
  1153. Xwhereis( char *path, char *file )
  1154. X{
  1155. X    char **eav, buf[100];
  1156. X    int  eac, j;
  1157. X
  1158. X    buf[0]=0;
  1159. X    if( path ) {
  1160. X        strcpy(buf,path);
  1161. X        appendslash(buf);
  1162. X    }
  1163. X    strcat(buf,".../");
  1164. X    strcat(buf,file);
  1165. X    if( !index( file, '*' ) && !index( file, '?') )
  1166. X        strcat(buf,"*");
  1167. X    if(eav=expand(buf,&eac)) {
  1168. X        for( j=0; j<eac && !dobreak(); j++ )
  1169. X            printf("%s\n",eav[j]);
  1170. X        free_expand(eav);
  1171. X    }
  1172. X}
  1173. X
  1174. Xdo_whereis( void )
  1175. X{
  1176. X    char buf[200], *prev, *devs;
  1177. X    int i;
  1178. X
  1179. X    if( index( av[1],':') || index( av[1],'/' ) )
  1180. X        { fprintf(stderr,"No paths please\n"); return 20; };
  1181. X
  1182. X    if( options&1 ) {
  1183. X        Myprocess->pr_WindowPtr = (APTR)(-1);
  1184. X        get_drives( devs=buf );
  1185. X        do {
  1186. X            prev=devs; devs=index(devs,0xA0);
  1187. X            if( devs ) *devs++=0; 
  1188. X            whereis( prev, av[1] );
  1189. X        } while( devs );
  1190. X        Myprocess->pr_WindowPtr = (APTR) o_noreq;
  1191. X    } else if( ac==2 ) {
  1192. X        whereis( NULL, av[1] );
  1193. X    } else {
  1194. X        for( i=2; i<ac; i++ ) {
  1195. X            strcpy(buf,av[i]);
  1196. X            appendslash( buf );
  1197. X            whereis( buf, av[1] );
  1198. X        }
  1199. X    }
  1200. X    return 0;
  1201. X}
  1202. X
  1203. Xdo_usage( void )
  1204. X{
  1205. X    int i;
  1206. X
  1207. X    if( ac==1 ) {
  1208. X        printf("Usage: usage [command...command]\n");
  1209. X        printf("[ ]=option   [ | ]=choice   { }=repetition   name...name=1 or more names\n");
  1210. X    } else 
  1211. X        for( i=1; i<ac; i++ )
  1212. X            show_usage( av[i] );
  1213. X    return 0;
  1214. X}
  1215. X
  1216. Xint NumMenus;
  1217. X
  1218. Xdo_menu( void )
  1219. X{
  1220. X    if( o_nowindow )
  1221. X        return 5;
  1222. X
  1223. X    if( options&1 )
  1224. X        remove_menu();
  1225. X
  1226. X    if( ac==2 )
  1227. X        show_usage( NULL );
  1228. X    else if( NumMenus<MAXMENUS && ac!=1)
  1229. X        install_menu( av+1, ac-1 );
  1230. X
  1231. X    set_menu();
  1232. X    return 0;
  1233. X}
  1234. X
  1235. X#define NUMITE 40
  1236. X#define TITWID 90
  1237. X#define ITEWID 148
  1238. X
  1239. Xstatic struct Menu DefaultMenu= {0, 0,0,TITWID,10, MENUENABLED,0,0};
  1240. Xstatic struct IntuiText DefaultIntuiText= {0,1,JAM2, 1,1,NULL,0,0};
  1241. Xstatic struct MenuItem DefaultMenuItem=
  1242. X  {0, 0,0,ITEWID,0, HIGHCOMP|ITEMTEXT|ITEMENABLED,0,0,0,0,0,0};
  1243. X
  1244. Xstruct Menu Menus[10];
  1245. Xchar *MenuCommand[MAXMENUS][MAXITEMS];
  1246. X
  1247. Xextern char *rindex();
  1248. X
  1249. Xstatic void
  1250. Xinstall_menu( char *mav[], int mac )
  1251. X{
  1252. X    struct TextAttr *ta;
  1253. X    struct Menu *m;
  1254. X    struct MenuItem *mi, **pmi;
  1255. X    struct IntuiText *it;
  1256. X    int y, i, fonthei;
  1257. X    char *p, *com;
  1258. X
  1259. X    if( o_nowindow || !Win )
  1260. X        return;
  1261. X
  1262. X    if( mac>=MAXITEMS )
  1263. X        mac=MAXITEMS-1;
  1264. X
  1265. X    ClearMenuStrip( Win );
  1266. X    Delay(3);
  1267. X
  1268. X    if( NumMenus )
  1269. X        Menus[NumMenus-1].NextMenu=Menus+NumMenus;
  1270. X    m  =&Menus[NumMenus];
  1271. X    *m =DefaultMenu;
  1272. X    m->LeftEdge  = NumMenus*TITWID;
  1273. X    m->MenuName  = strcpy(salloc(strlen(mav[0])+1),mav[0]);
  1274. X    if( strlen(m->MenuName)>TITWID/8 )
  1275. X        m->MenuName[TITWID/8+1]=0;
  1276. X    DefaultIntuiText.ITextFont=ta=Win->WScreen->Font;
  1277. X    DefaultMenuItem.Height=2+(fonthei=ta->ta_YSize);
  1278. X
  1279. X    y=0;
  1280. X    pmi=&m->FirstItem;
  1281. X    for( i=1; i<mac; i++) {
  1282. X        it =(void *)salloc(sizeof(struct IntuiText));
  1283. X        *it=DefaultIntuiText;
  1284. X        mi =(void *)salloc(sizeof(struct MenuItem ));
  1285. X        *mi=DefaultMenuItem;
  1286. X
  1287. X        com=NULL;
  1288. X        if( p=index(mav[i],',')) {
  1289. X            *p=0; com=++p;
  1290. X            if( p=index(com,',')) {
  1291. X                *p=0;
  1292. X                mi->Command=p[1];
  1293. X                mi->Flags |=COMMSEQ;
  1294. X            }
  1295. X        }
  1296. X
  1297. X        if( !com || !*com) {
  1298. X            com=strcpy(salloc(strlen(mav[i])+2),mav[i]);
  1299. X            MenuCommand[NumMenus][i-1]=com;
  1300. X            com+=strlen(com);
  1301. X            *com++=13;
  1302. X            *com=0;
  1303. X        } else {
  1304. X            MenuCommand[NumMenus][i-1]=strcpy(salloc(strlen(com)+1),com);
  1305. X        }
  1306. X
  1307. X        it->IText=(UBYTE *)strcpy(salloc(strlen(mav[i])+2),mav[i]);
  1308. X
  1309. X        *pmi= mi;
  1310. X        pmi = &mi->NextItem;
  1311. X        mi->TopEdge = y;
  1312. X        mi->ItemFill= (APTR)it;
  1313. X
  1314. X        y+=DefaultMenuItem.Height;
  1315. X    }
  1316. X
  1317. X    NumMenus++;
  1318. XMError:
  1319. X    return;
  1320. X}
  1321. X
  1322. X
  1323. Xvoid
  1324. Xremove_menu()
  1325. X{
  1326. X    if( NumMenus>0 ) {
  1327. X        struct MenuItem *mi, *nextmi;
  1328. X        int i,j;
  1329. X
  1330. X        for( i=0; i<NumMenus; i++ ) {
  1331. X            for( mi=Menus[i].FirstItem,j=0 ; mi; mi=nextmi,j++ ) {
  1332. X                free( ((struct IntuiText *)mi->ItemFill)->IText );
  1333. X                free( ((struct IntuiText *)mi->ItemFill) );
  1334. X                nextmi=mi->NextItem;
  1335. X                free(mi);
  1336. X                free(MenuCommand[i][j]);
  1337. X            }
  1338. X        }
  1339. X
  1340. X        NumMenus=0;
  1341. X        set_menu();
  1342. X    }
  1343. X}
  1344. X
  1345. X
  1346. Xvoid
  1347. Xset_menu()
  1348. X{
  1349. X    if( o_nowindow || !Win )
  1350. X        return;
  1351. X
  1352. X    if( NumMenus>0 )
  1353. X        SetMenuStrip( Win, Menus );
  1354. X    else 
  1355. X        ClearMenuStrip( Win );
  1356. X
  1357. X    Delay(3);
  1358. X}
  1359. X
  1360. Xdo_getenv( void )
  1361. X{
  1362. X    char buf[256], *val=buf, *getenv();
  1363. X
  1364. X    if( ac!=3 && ac!=2 ) {
  1365. X        show_usage( NULL );
  1366. X        return 20;
  1367. X    }
  1368. X    if( !Getenv(av[ac-1],buf,256))
  1369. X        val="";
  1370. X
  1371. X    if( ac==2 )
  1372. X        printf( "%s\n", val );
  1373. X    else 
  1374. X        set_var( LEVEL_SET, av[1], val );
  1375. X    return 0;
  1376. X}
  1377. X
  1378. X
  1379. Xdo_setenv( void )
  1380. X{
  1381. X    if( ac!=3 ) {
  1382. X        show_usage( NULL );
  1383. X        return 20;
  1384. X    } else
  1385. X        setenv( av[1], av[2] );
  1386. X    return 0;
  1387. X}
  1388. X
  1389. Xchar **
  1390. Xread_name( char *name, int *ac )
  1391. X{
  1392. X    FILE *file;
  1393. X    char **av=NULL;
  1394. X
  1395. X    *ac=0;
  1396. X    if( file=name ? fopen( name, "r") : stdin ) {
  1397. X        av=read_file( file, ac );
  1398. X        if( name ) fclose( file );
  1399. X    } else 
  1400. X        pError( name );
  1401. X    return av;
  1402. X}
  1403. X
  1404. X
  1405. Xchar **
  1406. Xread_file( FILE *file, int *ac )
  1407. X{
  1408. X    int buflen=4096, lines=0, i, offs;
  1409. X    char *buf, *ptr, *got=NULL, **lineptr;
  1410. X
  1411. X    if( !(buf=ptr=malloc( buflen )))
  1412. X        goto error;
  1413. X    do {
  1414. X        while( ptr+400 < buf+buflen && (got=fgets( ptr, 400, file ) ) &&
  1415. X               !dobreak()) {
  1416. X            ptr+=strlen(ptr)-1, lines++;
  1417. X            *ptr++=0;
  1418. X        }
  1419. X        if( ptr+256 < buf+buflen ) {
  1420. X            offs=ptr-buf;
  1421. X            if( !(buf=realloc( buf, buflen*=2 ) ) )
  1422. X                goto error;
  1423. X            ptr=buf+offs;
  1424. X        }
  1425. X    } while( got && !dobreak());
  1426. X    if( !(lineptr=(char **)malloc( (lines+1)*sizeof( char * ))))
  1427. X        goto error;
  1428. X    *lineptr++=buf;
  1429. X    for( ptr=buf, i=0; i<lines; i++ ) {
  1430. X        lineptr[i]=ptr;
  1431. X        ptr+=strlen(ptr)+1;
  1432. X    }
  1433. X    *ac=lines;
  1434. X    return lineptr;
  1435. X
  1436. Xerror:
  1437. X    if( buf ) free( buf );
  1438. X    fprintf( stderr, "Out of memory\n" );
  1439. X    *ac=0;
  1440. X    return NULL;
  1441. X}
  1442. X
  1443. Xvoid
  1444. Xfree_file( ptr )
  1445. X    char **ptr;
  1446. X{
  1447. X    if( ptr-- ) {
  1448. X        if( *ptr )
  1449. X            free( *ptr );
  1450. X        free(ptr);
  1451. X    }
  1452. X}
  1453. X
  1454. X
  1455. Xdo_qsort( void )
  1456. X{
  1457. X    char **lineptr;
  1458. X    int  lines, i;
  1459. X
  1460. X    if( ac==1 ) {
  1461. X        lineptr=read_file( stdin, &lines);
  1462. X        DirQuickSort( lineptr, lines, cmp, options&1, 0 );
  1463. X        prepscroll(0);
  1464. X        for( i=0; i<lines && !dobreak(); i++ ) {
  1465. X            quickscroll();
  1466. X            puts( lineptr[i] );
  1467. X        }
  1468. X        free_file( lineptr );
  1469. X    }
  1470. X    return 0;
  1471. X}
  1472. X
  1473. Xextern int w_width;
  1474. X
  1475. Xdo_truncate( void )
  1476. X{
  1477. X    char buf[256];
  1478. X    int  w=newwidth(), c;
  1479. X    char *ptr;
  1480. X
  1481. X    if( ac==2 )
  1482. X        w=atoi( av[1] );
  1483. X
  1484. X    prepscroll(0);
  1485. X    while( gets(buf) && !dobreak() ) {
  1486. X        for( c=0, ptr=buf; *ptr && c<w; ptr++ )
  1487. X            if( *ptr=='\t' )
  1488. X                c+=8-(c&7);
  1489. X            else if( *ptr==27 ) {
  1490. X                while( *ptr<'@' )
  1491. X                    ptr++;
  1492. X            } else 
  1493. X                c++;
  1494. X        *ptr=0;
  1495. X        quickscroll();
  1496. X        puts(buf);
  1497. X    }
  1498. X    return 0;
  1499. X}
  1500. X
  1501. Xint
  1502. Xdo_readfile( void )
  1503. X{
  1504. X    char **rav, *str=NULL;
  1505. X    int rac;
  1506. X
  1507. X    if( rav= read_name( ac>2 ? av[2] : NULL, &rac ) ) {
  1508. X        if( rac>255 ) rac=255;
  1509. X        if( str= compile_av( rav, 0, rac, 0xA0, 0 ) )
  1510. X            set_var( LEVEL_SET, av[1], str );
  1511. X        free_file( rav );
  1512. X    }
  1513. X    return str ? 0 : 20;
  1514. X}
  1515. X
  1516. Xint
  1517. Xdo_split( void )
  1518. X{
  1519. X    int i;
  1520. X    char *val, *gap, *oldval;
  1521. X
  1522. X    if( !(val=get_var( LEVEL_SET, av[1] )))
  1523. X        { fprintf( stderr, "Variable %s undefined\n", av[0] ); return 20; }
  1524. X    oldval=val=strcpy(salloc(strlen(val)+1),val);
  1525. X    for( i=2; i<ac-1; i++ ) {
  1526. X        if( gap=index(val,0xA0 )) *gap=0;
  1527. X        set_var( LEVEL_SET, av[i], val );
  1528. X        val="";
  1529. X        if( gap ) *gap=0xA0, val=gap+1;
  1530. X    }
  1531. X    set_var( LEVEL_SET, av[ac-1], val );
  1532. X    free(oldval);
  1533. X    return 0;
  1534. X}
  1535. X
  1536. Xchar *
  1537. Xcopyof( char *str )
  1538. X{
  1539. X    return strcpy(salloc(strlen(str)+1),str);
  1540. X}
  1541. X
  1542. Xint
  1543. Xdo_class( char *avline )
  1544. X{
  1545. X    CLASS *new;
  1546. X
  1547. X    if( options&1 ) {
  1548. X        avline=next_word(avline);
  1549. X        for( new=CRoot,CRoot=NULL; new; new=new->next )
  1550. X            Free(new);
  1551. X    }
  1552. X
  1553. X    if( ac==1 ) {
  1554. X        for( new=CRoot; new; new=new->next )
  1555. X            printf("%s\n",new->name);
  1556. X        return 0;
  1557. X    }
  1558. X
  1559. X    avline=next_word(avline);
  1560. X    if(!(new=malloc( strlen(avline)+5)))
  1561. X        ierror( NULL, 512 );
  1562. X    else {
  1563. X        new->next=NULL;
  1564. X        strcpy( new->name,avline );
  1565. X        if( CRoot )
  1566. X            LastCRoot->next=new;
  1567. X        else 
  1568. X            CRoot=new;
  1569. X        LastCRoot=new;
  1570. X    }
  1571. X    return 0;
  1572. X}
  1573. X
  1574. Xdo_getcl( void )
  1575. X{
  1576. X    char *s=getclass(av[1]);
  1577. X    if( s ) printf("%s\n",s);
  1578. X    return 0;
  1579. X}
  1580. X
  1581. Xdo_action( char *argline )
  1582. X{
  1583. X    char *args, err;
  1584. X    int abort=options&1;
  1585. X
  1586. X    args=compile_av( av,3,ac,' ',0 );
  1587. X    err=doaction(av[2],av[1],args);
  1588. X    if( !abort )
  1589. X        if( err==10 )    fprintf(stderr,"Can't identify %s\n", av[2] );
  1590. X        else if(err==11) fprintf(stderr,"Can't '%s' this file\n",av[1] );
  1591. X    return abort ? !err : err;
  1592. X}
  1593. END_OF_FILE
  1594. if test 28599 -ne `wc -c <'comm3.c'`; then
  1595.     echo shar: \"'comm3.c'\" unpacked with wrong size!
  1596. fi
  1597. # end of 'comm3.c'
  1598. fi
  1599. if test -f 'csh.doc.aa' -a "${1}" != "-c" ; then 
  1600.   echo shar: Will not clobber existing file \"'csh.doc.aa'\"
  1601. else
  1602. echo shar: Extracting \"'csh.doc.aa'\" \(26142 characters\)
  1603. sed "s/^X//" >'csh.doc.aa' <<'END_OF_FILE'
  1604. X
  1605. X        INSTRUCTIONS FOR SHELL VERSION: 5.10  11-Apr-1991
  1606. X        =================================================
  1607. X
  1608. X  Contents
  1609. X  --------
  1610. X
  1611. X    O.    Installation
  1612. X    I.    Description
  1613. X    II.    Overview of Major features
  1614. X    III.    Restrictions
  1615. X    IV.    PIPES
  1616. X    V.    Command Pre-processor
  1617. X    VI.    Command Line Editing
  1618. X    VII.    Function Keys
  1619. X    VIII.    Shell Commands
  1620. X    IX.    Special Set Variables
  1621. X    X.    Functions
  1622. X    XI.    Miscellaneous
  1623. X    XII.    Example source files
  1624. X    XIII.    Default values
  1625. X    XIV.    Object oriented features
  1626. X    XV.    Keymaps
  1627. X
  1628. X
  1629. X
  1630. XO.  Installation
  1631. X----------------
  1632. X
  1633. XYou  can  simply  invoke  csh  from  the  command  line or at the end of your
  1634. Xstartup-sequence,  because  csh  is, from the AmigaDOS standpoint, not a true
  1635. Xshell  like  l:shell-seg.   Nevertheless,  csh is 'pure', so if your archiver
  1636. Xforgot to set the 'p' bit, do it right now.
  1637. X
  1638. XProposed final setup:  If you want to make csh resident, do the following:
  1639. X
  1640. XKickstart 1.3
  1641. X1. Copy csh anywhere on your (hard)disk, e.g. dh1:tools
  1642. X2. Make sure your s:startup-sequence contains:
  1643. X    Resident CLI L:Shell-Seg SYSTEM PURE ADD
  1644. X    Resident dh1:tools/csh ADD
  1645. X    NewCLI FROM s:csh-startup
  1646. X    EndCLI
  1647. X3. Put the following in s:csh-startup
  1648. X    csh -r s:firstlogin.sh
  1649. X4. In s:firstlogin.sh, put any commands to be called only once, like setmap,
  1650. X   assign, setclock. This is a shell script, use # for comments, and don't
  1651. X   use .key type commands. At the end of this file, add
  1652. X    source s:login.sh
  1653. X5. In s:login.sh, you put any commands that need to be invocated on every
  1654. X   invocation, like 'alias', 'set' and so on.
  1655. X6. Put the following the s:cli-startup and s:shell-startup, so csh will be
  1656. X   started in any window opened by NewCLI or from workbench.
  1657. X    csh s:login.sh
  1658. X
  1659. XKickstart 2.0
  1660. X1. Copy csh anywhere on your (hard)disk, e.g. dh1:tools
  1661. X2. Make sure your s:startup-sequence contains:
  1662. X    Resident dh1:tools/csh ADD
  1663. X    csh s:firstlogin.sh
  1664. X3. Proceed from step 4 in kickstart 1.3
  1665. X
  1666. X
  1667. XAdditionally,  I  recommend  to  assign CSH:  somewhere and put your docs and
  1668. Xcshell  scripts there.  You can do the assign from inside the shell, it's not
  1669. Xneeded at startup.
  1670. X
  1671. X
  1672. XI.  DESCRIPTION
  1673. X---------------
  1674. X
  1675. XThis version of Shell is the successor of:
  1676. X    Shell V2.04 (C)Copyright 1986, Matthew Dillon, All Rights Reserved
  1677. X    Shell V2.04M-V2.07M by Steve Drew
  1678. X    Shell V2.08MI, V3.xxA and V4.xxA by Carlo Borreo & Cesare Dieni
  1679. X    Shell V5.xxL by Urban Mueller
  1680. X
  1681. XIf you have any wishes, bug reports or beer bottles, send them to:
  1682. X
  1683. X       FIDONET :  AUGL BBS, 2:302/906
  1684. X       INTERNET:  umueller@iiic.ethz.ch
  1685. Xor
  1686. X       Urban Mueller
  1687. X       Schulhausstrasse 83
  1688. X    CH-6312 Steinhausen
  1689. X       SWITZERLAND
  1690. X
  1691. XAny sign of intelligent life welcome!
  1692. X
  1693. XPlease  check the 'restrictions' and 'known bugs' paragraphs before reporting
  1694. Xany  bugs.  The support BBS is AUGL, +41 75 8 20 19, +41 75 8 20 18, +41 75 2
  1695. X15 87 (all lines USRobotics HST) login='cshell', password='support'
  1696. X
  1697. XFor  versions prior to 5.00 send suggestions/criticism/anything else to Carlo
  1698. XBorreo or Cesare Dieni at:
  1699. X
  1700. X       BITNET:  PERUGIA@ICNUCEVM.BITNET
  1701. X       FIDONET: 2:332/602.0@FIDONET
  1702. Xor
  1703. X       Carlo Borreo            Cesare Dieni
  1704. X       Via G. Berio 34        Via G. Taddei 3
  1705. X       I-18100 Imperia        I-56100 Pisa
  1706. X       Italy            Italy
  1707. X
  1708. XYou may distribute this program unmodified and for non-profit only.
  1709. X
  1710. X*** YOU MAY NOT MODIFY THIS PROGRAM AND REDISTRIBUTE IT ***
  1711. X
  1712. XIf  everyone  writes his own version of Shell and distributes it, we would be
  1713. Xcovered  by  Shell  versions.   If  you make a modification to Shell that you
  1714. Xwould  like  to  share  with  other users, please send us a DIFF output, or a
  1715. Xdescription of what you need.
  1716. X
  1717. XCREDITS
  1718. X-------
  1719. X
  1720. XArexx is a program by William Hawes.
  1721. XCygnus Ed Professional (C) 1988 CygnusSoft Software.
  1722. X
  1723. XMany  thanks  to  all  who  gave me feedback, namely Eddy Carroll, Patrizio
  1724. XRusconi,  Allard  Siemelink,  Magnus Heldestad, Roddi Walker, Roy Haverman,
  1725. XSteve Koren, Randell Jesup and all I forgot to mention.
  1726. X
  1727. X
  1728. XII. OVERVIEW
  1729. X------------
  1730. X
  1731. XShell  provides a convenient AmigaDos alternative command interface.  All its
  1732. Xcommands  are  internal  and  thus  does not rely on the c:  commands for any
  1733. Xfunctionality.
  1734. X
  1735. XMajor features include:
  1736. X    - command line editing
  1737. X    - simple history
  1738. X    - piping
  1739. X    - aliases with arguments
  1740. X    - variables & variable handling (embedded variables)
  1741. X    - file name expansion via wild carding ('?', '*' and more)
  1742. X    - conditionals (if/else etc..)
  1743. X    - source files  (w/ gotos and labels)
  1744. X    - tab file name completion
  1745. X    - object oriented features (file classes, actions)
  1746. X    - many built in commands to speed things up
  1747. X    - full functionality on VT terminals
  1748. X    - freely programmable command line editing
  1749. X
  1750. XShell  runs  on  minimum stack, for recursive aliases and source files better
  1751. Xincrease stack to 8K or more.
  1752. X
  1753. XIf you use CShell for the first time, remember the following:
  1754. X    - CShell internal commands must be lowercase & can be abbreviated
  1755. X    - AmigaDOS command 'Execute' causes some trouble. You cannot redirect
  1756. X      it, you must not rename it, and you get no return code.
  1757. X      You can also use 'source' to start your scripts, but you'll have
  1758. X      to rewrite them a bit. Besides the '.key'-type commands, 'source' 
  1759. X      is downward compatible with 'Execute'.
  1760. X    - You can always get more information on a command if csh.doc is
  1761. X      in the current directoy or in csh: (you will be able to modify 
  1762. X      this) and you enter 'man <command>'
  1763. X
  1764. X
  1765. XIII. RESTRICTIONS
  1766. X-----------------
  1767. X
  1768. XThe  following  applies only to Kickstart 2.0, and only to V36:  The INTERNAL
  1769. Xcommands cannot be started.  The same is true for the commands in C:  if they
  1770. Xwere  made  resident  using  the  AmigaDOS  'Resident' command (with cshell's
  1771. X'resident' they work).  Thus, you should disable the INTERNAL residents using
  1772. Xthe -i0 startup option if you have a V36 Kickstart.
  1773. X
  1774. XUnder  1.3, you can't start AmigaDOS residents directly.  But you can use the
  1775. X-r  startup  option,  which  will  copy the AmigaDOS resident list to the arp
  1776. Xresident  list once (and make those residents unremovable).  I'll try to find
  1777. Xa better solution.
  1778. X
  1779. XThe  best  choice  under  both kickstarts is to make only csh itself AmigaDOS
  1780. Xresident, all other commands, if any, ARP resident.  Under 1.3, you can start
  1781. Xthe  shell  (as any other commands) from the resident list only after you did
  1782. X'resident CLI l:Shell-seg' and 'newcli'.
  1783. X
  1784. XThe  c:Execute command cannot be redirected, does not return error codes, and
  1785. Xmight cause other problems.  It will not work at all if it has been renamed.
  1786. X
  1787. XThe  VDK:  handler and Frank Seidel's BootRam-Handler have a bug with setting
  1788. Xfile  dates,  so  when  using  the  copy command you should try the -d and -p
  1789. Xswitches, otherwise your file date will be bad.  (This is not a shell bug)
  1790. X
  1791. XIf using with conman it you may consider starting shell with the -a switch to
  1792. Xturn  off shell's command line editing and use conmans instead.  You'll lose,
  1793. Xhowever, many shell features like TAB file name completion.
  1794. X
  1795. XCB-handler  (a  tool that installs a scrollbar in the CLI window) is not 100%
  1796. Xcompatible  with  cshell.   The log will not always represent the real screen
  1797. Xcontents.
  1798. X
  1799. X
  1800. XIV. NOTES ON PIPES
  1801. X------------------
  1802. X
  1803. X    PIPES
  1804. X    PIPES  have  been implemented using temporary T:  files.  Thus, you
  1805. X    should be  careful  when  specifying  a 't:*' expansion as it might
  1806. X    include the temporary files. These files are deleted on completion
  1807. X    of the pipe segment.
  1808. X
  1809. X    The file names used are completely unique, even with multiple shell
  1810. X    running simultaneously.
  1811. X
  1812. X    My  favorite  new  feature is the fact that you can now redirect to
  1813. X    and  from,  and pipe internal commands.  'echo charlie >ram:x', for
  1814. X    instance.  Another favorite:
  1815. X
  1816. X    echo "echo mem | csh" | csh
  1817. X
  1818. X    No BCPL program should be output-append redirected (>>).
  1819. X
  1820. X
  1821. XV.  COMMAND PRE-PROCESSOR
  1822. X-------------------------
  1823. X
  1824. X    PREPROCESSING
  1825. X    Preprocessing is done on the command line before it is passed on to
  1826. X    an internal or external routine:
  1827. X
  1828. X    ^c    where c is a character is converted to that control character.
  1829. X        Thus, say '^l' for control-l.
  1830. X
  1831. X    \233    insert character code 233 octal. Do not use values between
  1832. X        200o and 232o, as they have special meanings. \240 is the
  1833. X        word separator.
  1834. X
  1835. X    $name    where name is a variable name.  Variable names can consist of
  1836. X        0-9, a-z, A-Z, and underscore (_).  The contents of the
  1837. X        specified variable is used.  If the variable doesn't exist,
  1838. X        the specifier is used.  That is, if the variable 'i' contains
  1839. X        'charlie', then '$i' -> 'charlie'.  If the variable 'i' doesn't
  1840. X        exist, then '$i'->'$i' .
  1841. X
  1842. X    ;    delimits commands.   echo charlie ; echo ben.
  1843. X
  1844. X    ' '    (a space). Spaces delimit arguments.
  1845. X
  1846. X    "string" a quoted string. Trailing quotes are optional. For instance,
  1847. X        if you want to echo five spaces and an 'a':
  1848. X
  1849. X        echo      a       -> a
  1850. X        echo "    a"      ->      a
  1851. X
  1852. X    \c    overide the meaning of special characters.  '\^a' is a
  1853. X        circumflex and an a rather than control-a.  To get a backslash,
  1854. X        you must say '\\'.
  1855. X
  1856. X        also used to overide alias searching for commands.
  1857. X
  1858. X    >file    specify output redirection.  All output from the command is
  1859. X        placed in the specified file.
  1860. X
  1861. X    >>file    specify append redirection (Does not work with BCPL programs).
  1862. X
  1863. X    <file    specify input redirection. The command takes input from the
  1864. X        file rather than the keyboard (note: not all commands require
  1865. X        input; it makes no sense to say 'echo <charlie' since
  1866. X        the 'echo' command only outputs its arguments).
  1867. X
  1868. X    |    PIPE specifier.  The output from the command on the left becomes
  1869. X        the input to the command on the right.  The current SHELL
  1870. X        implimentation uses temporary files to store the data.
  1871. X
  1872. X    !!    execute the previously executed command.
  1873. X    !nn    (nn is a number).  Insert the history command numbered n (see
  1874. X        the HISTORY command)
  1875. X    !partial search backwards through the history list for a command which
  1876. X        looks the same as 'partial', and execute it.
  1877. X
  1878. X    #    enter comment.  The rest of the line is discarded (note: \#
  1879. X        will, of course, overide the comment character's special
  1880. X        meaning)
  1881. X
  1882. X    {e hi;e ho} executes two commands as one, so they can be redirected
  1883. X        as one, so they can be redirected together (see ALIAS
  1884. X        command). The traling curly brace is optional.
  1885. X
  1886. X    $(foo)    insert the stdout of the command 'foo' at this position of
  1887. X        the command line. Every line of the output will count as one
  1888. X        argument. The closing parenthesis is optional.
  1889. X
  1890. X    `foo`    insert the stdout of the command 'foo' at this position of
  1891. X        the command line. Every blank separated word will count as
  1892. X        one argument. The trailing backtick is optional.
  1893. X
  1894. X    Please note the subtle differences between
  1895. X        alias count {echo one;echo two}
  1896. X        alias count "echo one;echo two
  1897. X    The first form will create an alias that contains a local alias. The
  1898. X    other will create a plain alias. Also, things within braces will not
  1899. X    be parsed more than once, therefore a backslash needs not be pre-
  1900. X    ceeded by a pair of backslashes. Thus the commands look the same as
  1901. X    if they were to be typed in at the prompt. To echo lots of '#', 
  1902. X    either use:
  1903. X        forever {echo \#
  1904. X        forever "echo \\\#
  1905. X    A block can spread over several line. Refer to the SOURCE command.
  1906. X
  1907. X
  1908. XVI. COMMAND LINE EDITING
  1909. X------------------------
  1910. X
  1911. X    o Command line can be up to 255 chars.
  1912. X    o Inserts  and  deletes  are handled correctly over multiple screen
  1913. X      lines.
  1914. X    o Shell  will  keep  track  of the line width should the window get
  1915. X      resized.
  1916. X
  1917. X    EDITING
  1918. X
  1919. X    -- MOVING --
  1920. X    Left Arrow      One character left
  1921. X    Right Arrow      One character right
  1922. X    Shift-Left Arrow  One word left
  1923. X    Shift-Right Arrow One word right
  1924. X    ESC-Left Arrow      Beginning of line (^A) (^Z)
  1925. X    ESC-Right Arrow      End of line       (^E)
  1926. X    -- DELETING --
  1927. X    Backspace      Previous character
  1928. X    Del          Character under cursor
  1929. X    ESC-Backspace      Previous word     (^W)
  1930. X    ESC-Del          Next word    
  1931. X    ESC-x-Backspace      To start of line  (^B)
  1932. X    ESC-x-Del      To end of line    (^K)
  1933. X    ESC-d          Entire line       (^X)
  1934. X    -- HISTORY --
  1935. X    Up Arrow      Recall previous commands
  1936. X    Down Arrow      Recall commands
  1937. X    Shift-Up Arow      Get history from partial (or number)
  1938. X    Shift-Down Arrow  Go below last command of history
  1939. X    ESC-Up Arrow      Get start of history
  1940. X    ESC-Down Arrow      Get end of history
  1941. X    ESC-!          Get history from partial (or number)
  1942. X    ^T          Insert tail (all but first word) of previous line
  1943. X    ^P          Duplicate previous word (useful for mv)
  1944. X    -- COMPLETION --
  1945. X    TAB          Inserts first matching file name
  1946. X    Shift-TAB      Inserts longest common substring
  1947. X    ESC-TAB          Inserts all matching file names
  1948. X    ESC-c          Does a quick cd on left word (TAB for cycling)
  1949. X    ESC-~          Inserts the last current directory
  1950. X    -- EXECUTING LINE --
  1951. X    Return          Executes line
  1952. X    ESC-Return      Executes this line of history & brings up next one
  1953. X    ^N          Next line. Don't exec this one but store history
  1954. X    ^\          EOF (directly exits)
  1955. X    -- MISCELLANEOUS --
  1956. X    ^L          Retype current line.
  1957. X    ^O          Echo a ^O
  1958. X    ^R          Repeat last command (don't play with this)
  1959. X    ^U          Undo/Redo last edit 
  1960. X    ESC-i          Toggle Insert/Overwrite
  1961. X    f1-f10          Execute command if variable exists.
  1962. X    F1-F10          More commands (Shifted f keys).
  1963. X    Help          Invokes help command
  1964. X
  1965. XWhenever  the cursor is placed on or directly after an incomplete file name
  1966. Xand   you  press  TAB,  CShell  inserts  for  the  first  filename  (sorted
  1967. Xalphabetically)  that  matches  the name part already typed.  Any wildcards
  1968. Xare allowed here, if none are given, '*' is appended.  Immediately pressing
  1969. XTAB  again  brings  up  the  next  file  name  that  matched the substring.
  1970. XShift-TAB  will  only  insert  the  as  much as is common to all files that
  1971. Xmatched  you  abbreviation.   If  pressed  again,  behaves  just  like TAB.
  1972. XESC-Tab  inserts  the  name  of the directory where you would have ended up
  1973. Xwith a quick cd to that substring.
  1974. X
  1975. XNote  that  ^D  now  means  'quit  batchfile' like under AmigaDOS and is no
  1976. Xlonger used for quitting CShell. If you want it back, enter 'keymap 0 4=41'
  1977. X
  1978. XThe  CTRL  keys FGVY are unset, feel free to map them to any function (see
  1979. Xchapter XV).  You can also remap all preset keys.
  1980. X
  1981. XVII. FUNCTION KEYS
  1982. X------------------
  1983. X
  1984. X    FUNKEY
  1985. X    Function keys now insert text to the current position on the command
  1986. X    line. They maybe terminated with a ^M (return). f1 would be non shifted
  1987. X    where as F1 is shifted.
  1988. X    Most of functions key have a default definition, but it may be changed.
  1989. X
  1990. X        $ set f1 dir df0:^M
  1991. X
  1992. X    will add the text 'dir df0:<return>' to the current line.
  1993. X
  1994. X        $ set f1 dir
  1995. X
  1996. X    would only add 'dir' you could then enter ' df0:<return>'
  1997. X
  1998. X
  1999. XVIII. SHELL COMMANDS
  2000. X--------------------
  2001. X
  2002. X    STARTUP OPTIONS
  2003. X    First to start shell from a CLI:
  2004. X
  2005. X    shell [-abcfiknstv] [-c command;command]
  2006. X    shell [-abcfiknstv] [batchfile1 ... batchfileN]
  2007. X
  2008. X     -a  AUX: mode. No command line editing and text highlighting
  2009. X     -b  starts shell in background, which means only task priority -1.
  2010. X     -c  allows execution of one command line and then exits out
  2011. X         of  shell.   This  is  useful for running an internal shell
  2012. X         commands in the background or from an external application:
  2013. X        Run csh -c "dir df0:; copy -r df0: df1: >nil:; echo Done"
  2014. X     -f  starts shell in foreground, which means only task priority 1.
  2015. X         you might reset this prioritiy to 0 at the end of your .login
  2016. X     -i0 disables INTERNAL residents. for V36 kickstarts.
  2017. X     -k  sets _nobreak before doing anything
  2018. X     -n  suppresses starting of s:.login
  2019. X     -r  copies the amiga resident list to the arp resident list. You
  2020. X         can't remove them anymore. No copying when under kick 2.0 or
  2021. X         if arp residents present.
  2022. X     -s  globally enables the star '*' as alias for #? in AmigaDOS 2.0
  2023. X     -t  terminal mode. You can use command line editing and text high-
  2024. X         lighting on a VT100 compatible terminal.
  2025. X     -v  sets _verbose to 'hs' before doing anything.
  2026. X
  2027. X    Under 1.3, the best thing you can do is to make csh resident using
  2028. X    the AmigaDOS Resident command in the startup-sequence, then start
  2029. X    it with the option -r, so you can start another resident csh from
  2030. X    inside csh. NOTE: Residents copied using -r cannot be removed! I
  2031. X    advise you to use the internal resident command for all but csh
  2032. X    itself.
  2033. X
  2034. X    COMMAND EXECUTION
  2035. X
  2036. X    Internal shell commands are case sensitive and may be abreviated.
  2037. X
  2038. X   The first argument is the command-name... here is (in order) how Shell
  2039. X   tries to execute it:
  2040. X
  2041. X    1)  The alias list is searched for an alias with an exactly 
  2042. X        matching name.
  2043. X    2)  Internal commands list is scanned for a command even partially
  2044. X        matching name (so you can, for instance, say resi for resident;
  2045. X        however, you should specify enough of a command to be unique).
  2046. X    3)  Then, the list of functions is scanned for a command that
  2047. X        matches completely. If one is found, the result of the function
  2048. X        is echoed to stdout.
  2049. X    4)  Now the command is assumed to be external. Arguments with spaces
  2050. X        or empty strings will be surrounded by quotes.
  2051. X    5)  If the file is a directory, a 'cd <file>' will be performed to
  2052. X        it.
  2053. X    6)  AmigaDOS and ARP resident list are scanned for it (you can use
  2054. X        Shell's 'resident' command to add/remove a file in the ARP list).
  2055. X    7)  If the file is in the current directory and it's executable, it
  2056. X        is started.
  2057. X    8)  Then it is searched in the AmigaDOS path and c: (NOTE: Path
  2058. X        assigns to C: under Kickstart 2.0 don't work; use 'path')
  2059. X    9)  Now, the shell path ($_path) is searched. If it's found and 
  2060. X        executable, it's be started. If it has the 's' bit set, it will
  2061. X        be 'c:Execute'd.
  2062. X    10) If there exists a file with the suffix '.sh' and the same root
  2063. X        in the current directory or in the shell path, it is 'source'd.
  2064. X    11) Then the variable _rxpath is examined. If there exists a file
  2065. X        with the suffix '.rexx' and the same root in the current direc-
  2066. X        tory or in '$_rxpath', 'RX <file>' will be performed.
  2067. X    12) If all failed, an 'exec' action is sent to the file. See chapter
  2068. X        XIV for more info on classes and actions.
  2069. X
  2070. X    To enforce that the external 'dir'-command is used, enter 'Dir'. Tt
  2071. X    is a good habit to uppercase the first letter of all external com-
  2072. X    mands, even if this is not necessary.
  2073. X
  2074. X    AUTOMATIC SOURCING may be accomplished by naming shell scripts with
  2075. X    a  .sh  suffix.   Thus,  if you say 'stuff' and the file 'stuff.sh'
  2076. X    exists in your current or anywhere in Shell search path (NOTE: won't
  2077. X    be found in the AmigaDOS path), it will be SOURCED  with all arguments
  2078. X    you  have given placed  in  the  $_passed variable. This is equivalent
  2079. X    to typing 'source stuff.sh'
  2080. X
  2081. X    WILD CARD EXPANSION
  2082. X    Most shell commands will accept multiple arguments that can
  2083. X    be as a result of wild card expansion.  Also when calling
  2084. X    an external command shell will first expand any wild cards
  2085. X    to separate arguments.  If you wish to have the external command
  2086. X    handle it's own wild carding you will need to insert quotes
  2087. X    around the special wild card characters or use an alias (see
  2088. X    explanation of 'alias')
  2089. X
  2090. X    eg.
  2091. X        arc a new.arc *.txt    - shell will expand and pass to arc
  2092. X        arc a new.arc "*.txt"    - let arc expand the wild cards.
  2093. X        alias arc "*a Arc $a"    - now shell will never expand
  2094. X
  2095. X    Wildcards allowed:
  2096. X
  2097. X    ?    match any single character
  2098. X    *    match any string
  2099. X    .../*    recursive search down ALL sub directories from current level
  2100. X    ~    exclude pattern matching specifier
  2101. X    !    synonym for ~, supported for compatibility
  2102. X    &    prefixed to patterns, ask confirmation for each file
  2103. X    []    character class
  2104. X    ~    the previous current directory (if separated)
  2105. X    Note that a pattern must contain a '?' or a '*', otherwise the other
  2106. X    special characters are not recognized. Furthermore, you cannot spe-
  2107. X    cify a single '?' as a pattern in the first argument to a command,
  2108. X    as this will be passed on to the command in order to show its usage.
  2109. X
  2110. X    Examples:
  2111. X
  2112. X    df0:.../*    all files in all directories on df0:
  2113. X    df0:.../!*.info    full directory tree of df0: but exclude
  2114. X            any ugly .info files.
  2115. X    !*.o !*.c    will result in ALL files matching since what
  2116. X            doesn't match the !*.o will match the !*.c
  2117. X    df1:&*        all files in root of df1:, but ask 
  2118. X            confirmation for each
  2119. X    *.[co]        all files ending in .c or .o
  2120. X    ~*.[co]        all files NOT ending in .c nor in .o
  2121. X    ~        the previous current directory
  2122. X    ~/*.c        all .c files in the previous current directory
  2123. X    ~//        the parent of the previous current directory
  2124. X    .        the current directory
  2125. X    ./foo.c        the same as foo.c
  2126. X    ..        the parent of the current directory
  2127. X    ../foo.c    the file foo.c in the parent directory
  2128. X
  2129. X    Note that some commands prevent wild card expansion. These are:
  2130. X      - dir, rpn, whereis, window
  2131. X    Those commands will expand the wild cards themselves. This is why
  2132. X      dir @without( *.? , *.o )
  2133. X    will not work. Instead use:
  2134. X      set arg @without( *.? , *.o );dir $arg
  2135. X
  2136. X    There is one exception to the rules given above: A single '?' as
  2137. X    the first argument will *not* expand in order to allow you to get
  2138. X    the usage of CLI and csh commands easily.
  2139. X
  2140. X    The   following   symbols  are  not  yet  supported  by  wild  card
  2141. X    expansions, but are accepted in search -w:
  2142. X
  2143. X    ( | )    OR matching
  2144. X    #    0 or more times the pattern following
  2145. X
  2146. X    Examples:
  2147. X
  2148. X    "k#a"        matches ka, kaa, kaaa, etc.
  2149. X    "hel(lo|p)"    matches hello or help.
  2150. X
  2151. X
  2152. XLIST OF COMMANDS:
  2153. X-----------------
  2154. X
  2155. X    ABORTLINE
  2156. X    Usage    : abortline
  2157. X    Example    : echo a;abort;echo b
  2158. X    Results    : a
  2159. X
  2160. X    Causes the rest of the line to be aborted. Intended for use in
  2161. X    conjunction with exception handling.
  2162. X
  2163. X    ACTION
  2164. X    Usage    : action [-a] actionname file [arguments]
  2165. X
  2166. X    Sends an action to a file. See chapter XIV CLASSES
  2167. X    Options:
  2168. X     -a (abort) returns 0 if failed and 1 if successful. Otherwise,
  2169. X                normal error codes (10 or 11) are returned
  2170. X
  2171. X    ADDBUFFERS
  2172. X    Usage    : addbuffers drive buffers [drive buffers ...]
  2173. X    Example    : addbuffers df0: 24
  2174. X
  2175. X    Just like AmigaDOS addbuffer command, causes new buffers to be
  2176. X    allocated for disk I/O. Each buffer costs 512 bytes of memory,
  2177. X    CHIP memory if a disk drive.
  2178. X
  2179. X    ALIAS
  2180. X    Usage    : alias [name [command string] ]
  2181. X    Example    : alias vt "echo Starting VT100;run sys:tools/vt100"
  2182. X
  2183. X    Sets a name to be a string. You can alias a single name to a set
  2184. X    of commands if you enclose them in quotes as above. By simply
  2185. X    typing vt, the command line above would be executed.
  2186. X    Aliases may call each other, but direct recursion is prohibited,
  2187. X    so the following works: alias ls "ls -s"
  2188. X    To prevent alias replacement, enter: \ls
  2189. X
  2190. X    By typing "alias name", you will get the alias for that name, while
  2191. X    with "alias" you get a list of all alias.
  2192. X
  2193. X    ARGUMENT PASSING TO AN ALIAS:
  2194. X
  2195. X    Usage    : alias name "%var[%var...] [ command_string ]"
  2196. X          alias name "*var[%var...] [ command_string ]"
  2197. X    Example    : alias xx "%q%w echo hi $q, you look $w
  2198. X          xx Steve great today
  2199. X    Results    : hi Steve, you look great today
  2200. X
  2201. X    The second form of the alias command allows passing of arguments
  2202. X    to any position within the command string via use of a variable
  2203. X    name. To pass arguments to the end of a command string this method
  2204. X    is actually not necessary. These variables are local, so they don't
  2205. X    destroy another variable with the same name.
  2206. X    If you specify multiple arguments, every argument will be assigned
  2207. X    one word, and the last argument will be assigned the rest of the
  2208. X    command line.
  2209. X
  2210. X    Using a '*' instead of the first '%' prevents wild card expansion:
  2211. X        alias zoo "*a zoo $a
  2212. X    To expand the wild cards after you got them, use
  2213. X        exec set a $a
  2214. X
  2215. X    IMPLICIT ALIASES:
  2216. X
  2217. X    Usage    : {command;command}
  2218. X          {%var command;command} arg arg
  2219. X    Example    : {%tmp echo $tmp $tmp} hello
  2220. X    Results    : hello hello
  2221. X
  2222. X    Curly braces define a temporary aliases. They can be redirected as
  2223. X    a whole, can have arguments and local variables. They count as
  2224. X    one argument, even if there are blanks inside (as with quotes), and
  2225. X    they may be nested. Complex alias definitions can use the braces
  2226. X    instead of quotes, although this will add some calling overhead.
  2227. X    The closing curly brace is optional if at the end of line.
  2228. X    Example:
  2229. X
  2230. X    alias assert {e "Are you sure? ";input -s sure
  2231. X
  2232. X    ASCII
  2233. X    Usage    : ascii
  2234. X          ascii string
  2235. X
  2236. X    If called without arguments, ascii outputs a complete ascii table.
  2237. X    Given a string, shows each character in ascii. Options:
  2238. X      -h shows numbers in hexadecimal
  2239. X      -o shows numbers in octal
  2240. X
  2241. X    ASET
  2242. X    Usage    : aset name value
  2243. X    Example    : aset INCLUDE include:
  2244. X
  2245. X    Set a variable in a way that is compatible with ARP/old Aztec set
  2246. X    command; this is completely different from ENV: Shell variable.
  2247. X
  2248. X    ASSIGN
  2249. X    Usage    : assign
  2250. X          assign logical
  2251. X          assign [-lnp] logical1 physical1 [logical2 physical2 ... ]
  2252. X
  2253. X    The first form shows all assigns.
  2254. X    The second form kills one assign.
  2255. X    The third form assigns logical1 to physical1 and so on. Options:
  2256. X     -l creates a late-binding assign under kick 2.0, normal otherwise
  2257. X     -n creates a non-binding assign under kick 2.0, normal otherwise
  2258. X     -p creates a path-assign under kick 2.0, cancelled otherwise
  2259. X    For definition of late/nonbinding, refer to your AmigaDOS manual.
  2260. X
  2261. X    BASENAME
  2262. X    Usage    : basename var path
  2263. X    Example    : basename x df0:c/Dir    # sets x to "Dir"
  2264. X
  2265. X    Sets var specified to basename of path.
  2266. X
  2267. X    CAT
  2268. X    Usage    : cat [-n][file file....]
  2269. X    Example    : cat foo.txt
  2270. X
  2271. X    Type the specified files onto the screen.  If no file is specified,
  2272. X    STDIN in used (note: ^\ is EOF).  CAT is meant to output text files
  2273. X    only. Specifying -n option you will get numbered lines.
  2274. X
  2275. X    CD
  2276. X    Usage    : cd [path]
  2277. X          cd -g device1 [device2 [device3 ...]]
  2278. X
  2279. X    Change your current working directory.  You may specify '..' to go
  2280. X    back one directory (this is a CD specific feature, and does not
  2281. X    work with normal path specifications).
  2282. X
  2283. X    In most cases, you'll no more have to use the CD command. Just type
  2284. X    the desired directory at the prompt (very handy in conjunction with
  2285. X    file name completion). Typing a ~ alone on a command line cd's
  2286. X    to prevous current directory.
  2287. X
  2288. X    There are two situations left when you still need it:
  2289. X
  2290. X    Entering 'cd *tem' will cd to the first name matched.
  2291. X
  2292. X    The second form generates a list (an ascii file) of all direc-
  2293. X    tories on the given devices. It will be stored in the file given
  2294. X    in $_qcd (default: 'csh:csh-qcd'). Note that this ascii file  will
  2295. X    not be merged but overwritten. Once you have generated this file,
  2296. X    you can cd to any directory on your harddisk(s) even if it's not
  2297. X    in the current directory.
  2298. X    If you have two directories of the same name and you use one of
  2299. X    them more, move the more important one to the beginning of the
  2300. X    qcd file. You might also sort the file.
  2301. X    It is legal to type just an abbreviation of the directory name
  2302. X    you want to cd to. No asterisk '*' necessary. If you end up in
  2303. X    the wrong directory, cd to the same directory again (best done
  2304. END_OF_FILE
  2305. if test 26142 -ne `wc -c <'csh.doc.aa'`; then
  2306.     echo shar: \"'csh.doc.aa'\" unpacked with wrong size!
  2307. fi
  2308. # end of 'csh.doc.aa'
  2309. fi
  2310. echo shar: End of archive 4 \(of 6\).
  2311. cp /dev/null ark4isdone
  2312. MISSING=""
  2313. for I in 1 2 3 4 5 6 ; do
  2314.     if test ! -f ark${I}isdone ; then
  2315.     MISSING="${MISSING} ${I}"
  2316.     fi
  2317. done
  2318. if test "${MISSING}" = "" ; then
  2319.     echo You have unpacked all 6 archives.
  2320.     rm -f ark[1-9]isdone
  2321. else
  2322.     echo You still need to unpack the following archives:
  2323.     echo "        " ${MISSING}
  2324. fi
  2325. ##  End of shell archive.
  2326. exit 0
  2327. -- 
  2328. Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
  2329. Mail comments to the moderator at <amiga-request@uunet.uu.net>.
  2330. Post requests for sources, and general discussion to comp.sys.amiga.misc.
  2331.